package com.xl.basic.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xl.basic.entity.*;
import com.xl.basic.entity.param.*;
import com.xl.basic.entity.result.UserResult;
import com.xl.basic.service.UserService;
import com.xl.basic.utils.LoginUtils;
import com.xl.basic.utils.PropUtils;
import com.xl.dao.domain.XlUser;
import com.xl.dao.mapper.XlUserMapper;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;

/**
 * @author 钟勇
 * Create in 2023/8/30 13:07
 */

@Service
@RequiredArgsConstructor
public class UserServiceImpl implements UserService {

    private final XlUserMapper userMapper;

    @Override
    public Result<String> addUser(@NonNull AddUserParam param, UserInfo operator) {
        if (StrUtil.isBlank(param.getPhone()) && StrUtil.isBlank(param.getEmail())) {
            return ResultEnums.ParamError.getResult("邮箱和电话不能同时为空");
        }

        if (userMapper.selectCount(new LambdaUpdateWrapper<XlUser>()
                .eq(XlUser::getState, 1)
                .and(w -> w.eq(StrUtil.isNotBlank(param.getPhone()), XlUser::getPhone, param.getPhone())
                        .or()
                        .eq(StrUtil.isNotBlank(param.getEmail()), XlUser::getEmail, param.getEmail())
                )
        ) > 0) {
            return ResultEnums.BusinessError.getResult("邮箱或电话已存在");
        }

        //没有输入密码的写入默认密码
        if (StrUtil.isBlank(param.getPassword())) {
            Properties.Auth auth = PropUtils.getProp().getAuth();
            param.setPassword(auth.getDefaultPassword());
        }

        //加密密码
        param.setPassword(LoginUtils.encryptPassword(param.getPassword()));

        XlUser userInfo = BeanUtil.copyProperties(param, XlUser.class);
        userInfo.setState(1)
                .setAddTime(LocalDateTime.now())
                .setAddUser(operator == null ? null : operator.getUserId());

        if (userMapper.insert(userInfo) <= 0) {
            return ResultEnums.Exception.getResult("用户写入失败");
        }

        return ResultEnums.Success.getDataResult(userInfo.getUserId());
    }

    @Override
    public Result<Object> updUser(@NonNull UpdUserParam param, UserInfo operator) {
        XlUser oriUserInfo = userMapper.selectById(param.getUserId());
        if (oriUserInfo == null || !oriUserInfo.getState().equals(1)) {
            return ResultEnums.BusinessError.getResult("用户不存在");
        }

        if (oriUserInfo.getDisableFlag() == 1) {
            return ResultEnums.BusinessError.getResult("用户已禁用，无法编辑");
        }

        if (StrUtil.isNotBlank(param.getPhone()) || StrUtil.isNotBlank(param.getEmail())) {
            if (userMapper.selectCount(new LambdaUpdateWrapper<XlUser>()
                    .eq(XlUser::getState, 1)
                    .ne(XlUser::getUserId, param.getUserId())
                    .and(w -> w.eq(StrUtil.isNotBlank(param.getPhone()), XlUser::getPhone, param.getPhone())
                            .or()
                            .eq(StrUtil.isNotBlank(param.getEmail()), XlUser::getEmail, param.getEmail())
                    )
            ) > 0) {
                return ResultEnums.BusinessError.getResult("邮箱或电话已存在");
            }
        }

        XlUser userInfo = BeanUtil.copyProperties(param, XlUser.class);
        userInfo.setUpdTime(LocalDateTime.now())
                .setUpdUser(operator == null ? null : operator.getUserId());

        if (userMapper.updateById(userInfo) <= 0) {
            return ResultEnums.Exception.getResult("用户编辑失败");
        }

        return ResultEnums.Success.getResult();
    }

    @Override
    public Result<Object> updUserPassword(@NonNull UpdUserPasswordParam param, UserInfo operator) {
        XlUser oriUserInfo = userMapper.selectById(param.getUserId());
        if (oriUserInfo == null || !oriUserInfo.getState().equals(1)) {
            return ResultEnums.BusinessError.getResult("用户不存在");
        }

        //加密密码
        param.setPassword(LoginUtils.encryptPassword(param.getPassword()));

        if (userMapper.updateById(new XlUser()
                .setUserId(param.getUserId())
                .setPassword(param.getPassword())
                .setUpdTime(LocalDateTime.now())
                .setUpdUser(operator == null ? null : operator.getUserId())
        ) <= 0) {
            return ResultEnums.Exception.getResult("用户编辑失败");
        }

        return ResultEnums.Success.getResult();
    }

    @Override
    public Result<Object> disableUser(@NonNull String userId, UserInfo operator) {
        XlUser oriUserInfo = userMapper.selectById(userId);
        if (oriUserInfo == null || !oriUserInfo.getState().equals(1)) {
            return ResultEnums.BusinessError.getResult("用户不存在");
        }

        if (oriUserInfo.getDisableFlag() == 1) {
            return ResultEnums.Success.getResult();
        }

        if (userMapper.updateById(new XlUser()
                .setUserId(userId)
                .setDisableFlag(1)
                .setUpdTime(LocalDateTime.now())
                .setUpdUser(operator == null ? null : operator.getUserId())
        ) <= 0) {
            return ResultEnums.Exception.getResult("用户禁用失败");
        }

        return ResultEnums.Success.getResult();
    }

    @Override
    public Result<Object> enabledUser(@NonNull String userId, UserInfo operator) {
        XlUser oriUserInfo = userMapper.selectById(userId);
        if (oriUserInfo == null || !oriUserInfo.getState().equals(1)) {
            return ResultEnums.BusinessError.getResult("用户不存在");
        }

        if (oriUserInfo.getDisableFlag() != 1) {
            return ResultEnums.Success.getResult();
        }

        if (userMapper.updateById(new XlUser()
                .setUserId(userId)
                .setDisableFlag(0)
                .setUpdTime(LocalDateTime.now())
                .setUpdUser(operator == null ? null : operator.getUserId())
        ) <= 0) {
            return ResultEnums.Exception.getResult("用户解禁失败");
        }

        return ResultEnums.Success.getResult();
    }

    @Override
    public Result<UserResult> getUserInfo(@NonNull String userId) {
        Result<List<UserResult>> listRes = queryUserList(new QueryUserParam().setUserId(userId));
        if (listRes.isErr()) {
            return listRes.create();
        }

        List<UserResult> list = listRes.getResult();
        if (list == null || list.isEmpty()) {
            return ResultEnums.BusinessError.getResult("未找到用户信息");
        }

        return ResultEnums.Success.getDataResult(list.get(0));
    }

    @Override
    public Result<UserResult> getUserInfoByPhone(@NonNull String phone) {
        Result<List<UserResult>> listRes = queryUserList(new QueryUserParam().setPhone(phone));
        if (listRes.isErr()) {
            return listRes.create();
        }

        List<UserResult> list = listRes.getResult();
        if (list == null || list.isEmpty()) {
            return ResultEnums.BusinessError.getResult("未找到用户信息");
        }

        return ResultEnums.Success.getDataResult(list.get(0));
    }

    @Override
    public Result<List<UserResult>> queryUserList(@NonNull QueryUserParam param) {
        List<XlUser> xlUserList = userMapper.selectList(getQueryUserWrapper(param));
        List<UserResult> list = xlUserList.stream()
                .map(item -> BeanUtil.copyProperties(item, UserResult.class))
                .toList();
        return ResultEnums.Success.getListResult(list);
    }

    @Override
    public Result<List<UserResult>> queryUserPage(@NonNull QueryUserParam param, SPage sPage) {
        Page<XlUser> page = userMapper.selectPage(SPage.getPage(sPage), getQueryUserWrapper(param));

        List<XlUser> records = page.getRecords();
        long total = page.getTotal();

        List<UserResult> list = records.stream()
                .map(item -> BeanUtil.copyProperties(item, UserResult.class))
                .toList();
        return ResultEnums.Success.getPageResult(list, total);
    }

    private Wrapper<XlUser> getQueryUserWrapper(@NonNull QueryUserParam param) {
        LambdaQueryWrapper<XlUser> wrapper = new LambdaQueryWrapper<XlUser>()
                .eq(XlUser::getState, 1)
                .eq(StrUtil.isNotBlank(param.getUserId()), XlUser::getUserId, param.getUserId())
                .eq(param.getDisableFlag() != null, XlUser::getDisableFlag, Boolean.TRUE.equals(param.getDisableFlag()) ? 1 : 0)
                .eq(StrUtil.isNotBlank(param.getEmail()), XlUser::getEmail, param.getEmail())
                .eq(StrUtil.isNotBlank(param.getPhone()), XlUser::getPhone, param.getPhone());

        String userLike = param.getUserLike();
        if (StrUtil.isNotBlank(userLike)) {
            wrapper.and(w -> w.like(XlUser::getEmail, userLike)
                    .or()
                    .like(XlUser::getPhone, userLike)
                    .or()
                    .like(XlUser::getUserName, userLike)
            );
        }

        if (param.getRoleId() != null) {
            wrapper.exists("""
                    SELECT 1 FROM xl_role_user
                        WHERE state = 1 AND role_id = {0} AND user_id = xl_user.user_id
                    """, param.getRoleId());
        }

        return wrapper;


    }
}
